#include "receivepackthread.h"
#include <QDebug>

ReceivePackThread::ReceivePackThread(QSerialPort *port)
{
    m_port = port;
    //moveToThread(this);  // 将线程内的 QSerialPort 移到当前线程中
}

void ReceivePackThread::run() // receive from 下位机.
{
    char pack[9];
    char cmd;
    char param;
    int data;

    while(1)
    {
        m_port->waitForReadyRead(100);
        int ret = m_port->bytesAvailable();
        if(ret == 0) continue;

        m_port->read((char*)pack,sizeof(pack));
        qDebug() << "read: " << ret << " bytes.";
        qDebug() << "datas:" << pack[0] << " " << pack[1] << " " << pack[2] << " " << pack[3] << " " << pack[4]
                             << " " << pack[5] << " " << pack[6] << " " << pack[7] << " " << pack[8];

        if(parsePack((unsigned char*)pack,sizeof(pack),&cmd,&param,&data))
        {
            qDebug() << "解析下位机返回包成功！";
            emit receivePackData(cmd,param,data);
        }
        else
        {
            qDebug() << "下位机返回包非法！";
        }
    }
}

/*说是解析，其实就是判断下位机发回的数据是否合法，然后把下位机响应包的数据通过emit信号带出去，然后渲染在MainWindow上*/
bool ReceivePackThread::parsePack(unsigned char pack[], int size, char *cmd, char *param, int *data)
{
    if(!pack || size < 9) return false;

    if(pack[0] == 0xEF && pack[8] == 0xFE)
    {
        //判断偶检验是否正确
        int count = 0;
        for(int i = 1 ; i<=7 ; i++)
        {
            char byte = pack[i];
            for(int j = 0 ; j<8 ; j++)
            {
                if(byte & 1) count++;
                byte >>= 1;
            }
        }
        if(count & 1) return false;
        //
        *cmd = pack[1];
        *param = pack[2];
        *data = pack[3] | (pack[4] << 8) | (pack[5] << 16) | (pack[6] << 24);

        return true;
    }

    return false;
}
